package com.bing.bingPro.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bing.bingPro.controller.dto.MgDamTableRelationDTO;
import com.bing.bingPro.controller.vo.TableRelationVO;
import com.bing.bingPro.entity.MgDamDbInfo;
import com.bing.bingPro.entity.MgDamTableInfo;
import com.bing.bingPro.entity.MgDamTableRelation;
import com.bing.bingPro.mapper.MgDamTableRelationMapper;
import com.bing.bingPro.service.MgDamDbInfoService;
import com.bing.bingPro.service.MgDamTableInfoService;
import com.bing.bingPro.service.MgDamTableRelationService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 29821
 * @description 针对表【mg_dam_table_relation(数据资产数据表关系配置)】的数据库操作Service实现
 * @createDate 2024-03-18 10:23:34
 */
@Service
public class MgDamTableRelationServiceImpl extends ServiceImpl<MgDamTableRelationMapper, MgDamTableRelation>
        implements MgDamTableRelationService {

    @Resource
    private MgDamTableRelationMapper mgDamTableRelationMapper;

    @Resource
    private MgDamDbInfoService mgDamDbInfoService;

    @Resource
    private MgDamTableInfoService mgDamTableInfoService;

    @Override
    public Map<String, Object> list(MgDamTableRelationDTO infoDTO) {
        Long rootTableId = infoDTO.getTableId();
        Set<Long> processedIds = new HashSet<>();
        Map<String, Object> childResult = buildNodes(rootTableId, processedIds, true); // 构建子节点
        processedIds.clear();
        Map<String, Object> parentResult = buildParents(rootTableId, processedIds); // 构建父节点
        return mergeNodeData(childResult, parentResult, rootTableId); // 合并子节点和父节点数据
    }

    @Override
    public Map<String, Object> list2(MgDamTableRelationDTO infoDTO) {
        Long dbId = infoDTO.getDbId();
        MgDamDbInfo mgDamDbInfo = mgDamDbInfoService.getById(dbId);
        String dbType = mgDamDbInfo.getDbType();
        // 查询当前表数据
        LambdaQueryWrapper<MgDamTableInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MgDamTableInfo::getDbId, dbId);
        // 查询所选库对应表
        List<MgDamTableInfo> mysqlTableList = mgDamTableInfoService.list(queryWrapper);
        System.out.println(111);
        return null;
    }

    private Map<String, Object> buildNodes(Long nodeId, Set<Long> processedIds, boolean isRoot) {
        if (processedIds.contains(nodeId)) {
            return Collections.emptyMap();
        }
        processedIds.add(nodeId);
        Map<String, Object> node = getNode(nodeId);
        if (!isRoot) {
            node.put("relationship", "下游");
        }
        // 构建子节点
        List<Long> childIds = getChildTableIds(nodeId);
        List<Map<String, Object>> children = childIds.stream()
                .map(childId -> buildNodes(childId, processedIds, false))
                .filter(map -> !map.isEmpty())
                .collect(Collectors.toList());
        if (!children.isEmpty()) {
            node.put("children", children);
        }
        return node;
    }

    private Map<String, Object> buildParents(Long nodeId, Set<Long> processedIds) {
        if (processedIds.contains(nodeId)) {
            return Collections.emptyMap();
        }
        processedIds.add(nodeId);
        Map<String, Object> node = getNode(nodeId);
        node.put("relationship", "上游");
        // 添加父节点
        List<Long> parentIds = getParentTableIds(nodeId);
        List<Map<String, Object>> parents = new ArrayList<>();
        for (Long parentId : parentIds) {
            Map<String, Object> parentNode = buildParents(parentId, processedIds);
            parents.add(parentNode);
        }

        if (!parents.isEmpty()) {
            node.put("parents", parents);
        }
        return node;
    }

    private Map<String, Object> getNode(Long nodeId) {
        TableRelationVO relationVO = mgDamTableRelationMapper.selectRelationList(nodeId);
        Map<String, Object> node = new HashMap<>();
        node.put("id", "id" + nodeId);
        node.put("label", nodeId.toString());
        node.put("archive", getTableName(nodeId));
        node.put("type", relationVO.getDbType());
        node.put("schema", relationVO.getDbSchema());
        return node;
    }

    @SuppressWarnings("unchecked")
    public Map<String, Object> mergeNodeData(Map<String, Object> childData, Map<String, Object> parentData, Long rootTableId) {
        // 复制子节点数据到结果中
        Map<String, Object> result = new HashMap<>(childData);

        // 从父节点数据中获取 "parents" 列表，并确保它们不为空
        List<Map<String, Object>> parents = (List<Map<String, Object>>) parentData.getOrDefault("parents", Collections.emptyList());

        List<Map<String, Object>> convertedParents = parents.stream()
                .filter(parent -> !parent.isEmpty())
                .map(this::convertParentsToChildren)  // 转换 parents 键为 children 键
                .collect(Collectors.toList());

        // 获取当前的 "children" 列表
        List<Map<String, Object>> currentChildren = (List<Map<String, Object>>) result.getOrDefault("children", new ArrayList<>());

        // 将转换后的父节点添加到 "children" 中
        currentChildren.addAll(convertedParents);
        result.put("children", currentChildren);
        result.put("arrId", mgDamTableRelationMapper.selectRelationId(rootTableId));
        return result;
    }

    @SuppressWarnings("unchecked")
    public Map<String, Object> convertParentsToChildren(Map<String, Object> node) {
        // 将 'parents' 键转换为 'children' 键
        if (node.containsKey("parents")) {
            Object parents = node.remove("parents");
            node.put("children", parents);
        }
        // 对新的 children 进行递归处理
        if (node.containsKey("children")) {
            List<Map<String, Object>> children = (List<Map<String, Object>>) node.get("children");
            List<Map<String, Object>> convertedChildren = children.stream()
                    .map(this::convertParentsToChildren)  // 对子节点进行递归处理
                    .collect(Collectors.toList());
            node.put("children", convertedChildren);
        }
        return node;
    }


    /**
     * 获取上游关系列表
     *
     * @param childTableId
     * @return 上游关系ID列表
     */
    private List<Long> getParentTableIds(Long childTableId) {
        List<Long> parentIds = new ArrayList<>();
        List<Long> parentIdList = mgDamTableRelationMapper.selectRelationId(childTableId);
        for (Long childId : parentIdList) {
            parentIds.add(childId);
            parentIds.addAll(getParentTableIds(childId));
        }
        return parentIds;
    }

    private String getTableName(Long tableId) {
        return mgDamTableRelationMapper.selectTableName(tableId);
    }

    /**
     * 获取下游关系列表
     *
     * @param parentTableId
     * @return 下游关系ID列表
     */
    private List<Long> getChildTableIds(Long parentTableId) {
        List<Long> childIds = mgDamTableRelationMapper.selectDownRelation(parentTableId);
        List<Long> grandChildIds = new ArrayList<>();
        for (Long childId : childIds) {
            grandChildIds.add(childId);
            grandChildIds.addAll(getChildTableIds(childId));
        }
        return grandChildIds;
    }

    public static void main(String[] args) {
        List<String> mgTableList = Arrays.asList("北京", "福建");
        Set<String> mgTableSet = new HashSet<>(mgTableList);
        List<String> tableList = new ArrayList<>(Arrays.asList("安徽", "北京", "福建"));
        tableList.removeIf(mgTableSet::contains);
        System.out.println(tableList);
    }
}




